package com.rgp.servicemap.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rgp.internalcommon.common.CommonStatusEnum;
import com.rgp.internalcommon.common.UrlConstants;
import com.rgp.internalcommon.dto.ResponseResult;
import com.rgp.internalcommon.dto.TrackPoint;
import com.rgp.internalcommon.dto.TrackPointsDto;
import com.rgp.internalcommon.dto.TrackRequestDto;
import com.rgp.internalcommon.response.ErrorTrackPoint;
import com.rgp.internalcommon.response.ErrorTrackPointsResponse;
import com.rgp.internalcommon.response.TrackResponse;
import com.rgp.internalcommon.response.TrsearchResponse;
import com.rgp.internalcommon.utils.JointUrlUtils;
import com.rgp.servicemap.service.TrackService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @author nhp
 * @version 1.0
 * @description TODO
 * @date 2024-04-19 20:15
 */
@Service
public class TrackServiceImpl implements TrackService {

    @Value("${amap.key}")
    private String secretKey;

    @Value("${amap.sid}")
    private String secretSid;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public ResponseResult addTrack(Long tid) {

        Map<String, String> map = new HashMap<>();
        map.put("key",secretKey);
        map.put("sid",secretSid);
        map.put("tid",tid + "");

        String url = JointUrlUtils.combineUrlAndParameters(UrlConstants.CREATE_TRACK_URL, map);
        String restResponse = restTemplate.postForObject(url, null, String.class);
        JSONObject jsonObject = JSONObject.parseObject(restResponse);
        String errcode = jsonObject.getInteger("errcode") + "";
        if (!errcode.equals("10000")){
            return ResponseResult.fail(CommonStatusEnum.CREATE_TRACK_ERROR);
        }
        JSONObject data = jsonObject.getJSONObject("data");
        String trname = data.getString("trname");
        Integer trid = data.getInteger("trid");
        TrackResponse trackResponse = new TrackResponse();
        trackResponse.setTrid(trid);
        trackResponse.setTrname(trname);
        return ResponseResult.success(trackResponse);
    }

    @Override
    public ResponseResult deleteTrack(TrackRequestDto trackRequestDto) {
        Map<String, String> map = new HashMap<>();
        map.put("key",secretKey);
        map.put("sid",secretSid);
        map.put("tid",trackRequestDto.getTid());
        map.put("trid",trackRequestDto.getTrid());

        String url = JointUrlUtils.combineUrlAndParameters(UrlConstants.DELETE_TRACK_URL, map);
        String restResponse = restTemplate.postForObject(url, null, String.class);
        JSONObject jsonObject = JSONObject.parseObject(restResponse);
        String errcode = jsonObject.getInteger("errcode") + "";
        if (!errcode.equals("10000")){
            return ResponseResult.fail(CommonStatusEnum.DELETE_TRACK_ERROR);
        }
        return ResponseResult.success();
    }

    @Override
    public ResponseResult upload(TrackPointsDto trackPointsDto) {

        StringBuilder builder = new StringBuilder();
        builder.append(UrlConstants.TRACK_POINTS_UPLOAD_URL);
        builder.append("key=");
        builder.append(secretKey);
        builder.append("&");
        builder.append("sid=");
        builder.append(secretSid);
        builder.append("&");
        builder.append("tid=");
        builder.append(trackPointsDto.getTid() + "");
        builder.append("&");
        builder.append("trid=");
        builder.append(trackPointsDto.getTrid() + "");
        builder.append("&");
        builder.append("points=");
        builder.append("%5B");
        TrackPoint[] points = trackPointsDto.getPoints();
        TrackPoint point = null;
        for (int i = 0;i < points.length;i++){
            point = points[i];
            builder.append("%7B");
            builder.append("%22location%22");
            builder.append("%3A");
            builder.append("%22" + point.getLocation() + "%22");
            builder.append("%2C");
            builder.append("%22locatetime%22");
            builder.append("%3A");
            builder.append(point.getLocatetime());
            builder.append("%2C");
            builder.append("%22speed%22");
            builder.append("%3A");
            builder.append(point.getSpeed());
            builder.append("%2C");
            builder.append("%22direction%22");
            builder.append("%3A");
            builder.append(point.getDirection());
            builder.append("%2C");
            builder.append("%22height%22");
            builder.append("%3A");
            builder.append(point.getHeight());
            builder.append("%2C");
            builder.append("%22accuracy%22");
            builder.append("%3A");
            builder.append(point.getAccuracy());
            builder.append("%7D");
            if (i != (points.length - 1)){
                builder.append("%2C");
            }
        }
        builder.append("%5D");
        String url = builder.toString();
        String restResponse = restTemplate.postForObject(URI.create(url), null, String.class);
        JSONObject jsonObject = JSONObject.parseObject(restResponse);
        String errcode = jsonObject.getInteger("errcode") + "";
        if (!errcode.equals("10000")){
            JSONObject data = jsonObject.getJSONObject("data");
            JSONArray errorpoints = data.getJSONArray("errorpoints");
            ArrayList<ErrorTrackPoint> list = new ArrayList<>(errorpoints.size());
            for (int i = 0;i < errorpoints.size();i++){
                JSONObject object = errorpoints.getJSONObject(i);
                String paramErrInfo = object.getString("_param_err_info");
                String errPointIndex = object.getString("_err_point_index");
                String location = object.getString("location");
                Long locatetime = object.getLong("locatetime");
                Integer speed = object.getInteger("speed");
                Integer direction = object.getInteger("direction");
                Integer height = object.getInteger("height");
                Integer accuracy = object.getInteger("accuracy");
                ErrorTrackPoint errorTrackPoint = new ErrorTrackPoint();
                errorTrackPoint.setParamErrInfo(paramErrInfo);
                errorTrackPoint.setErrPointIndex(errPointIndex);
                errorTrackPoint.setLocation(location);
                errorTrackPoint.setLocatetime(locatetime);
                errorTrackPoint.setSpeed(speed);
                errorTrackPoint.setDirection(direction);
                errorTrackPoint.setHeight(height);
                errorTrackPoint.setAccuracy(accuracy);
                list.add(errorTrackPoint);
            }
            ErrorTrackPointsResponse response = new ErrorTrackPointsResponse();
            response.setErrorpoints(list.toArray(new ErrorTrackPoint[list.size()]));
            return ResponseResult.fail(CommonStatusEnum.UPLOAD_TRACK_POINTS_ERROR,response);
        }
        return ResponseResult.success();
    }

    @Override
    public ResponseResult<TrsearchResponse> trsearch(Long tid, Integer trid, String startTime, String endTime) {
        Map<String, String> map = new HashMap<>();
        map.put("key",secretKey);
        map.put("sid",secretSid);
        map.put("tid",tid + "");
        map.put("trid",trid + "");
        map.put("starttime",startTime);
        map.put("endtime",endTime);
        String url = JointUrlUtils.combineUrlAndParameters(UrlConstants.TRACK_TERMINAL_TRSEARCH_URL, map);
        String jsonResponse = restTemplate.getForObject(url, String.class);
        JSONObject jsonObject = JSONObject.parseObject(jsonResponse);
        String errcode = jsonObject.getString("errcode");
        if (!errcode.equals("10000")){
            return ResponseResult.fail(CommonStatusEnum.TRACK_TERMINAL_TRSEARCH_ERROR);
        }
        JSONObject data = jsonObject.getJSONObject("data");
        Integer counts = data.getInteger("counts");
        Long distance = null;
        Long time = null;
        if (counts == 0){
            return ResponseResult.fail(CommonStatusEnum.TERMINAL_TRACK_NOT_EXIST_ERROR);
        }else {
            JSONArray tracks = data.getJSONArray("tracks");
            JSONObject track = tracks.getJSONObject(0);
            distance = track.getLong("distance");
            time = track.getLong("time");
        }
        TrsearchResponse response = new TrsearchResponse();
        response.setDriverMile(distance);
        response.setDriverTime(time);
        return ResponseResult.success(response);
    }
}